/*
 * 描          述:  <描述>
 * 修  改   人:  brady
 * 修改时间:  3-2-25
 * <修改描述:>
 */
package com.tx.core.util;

import java.text.DecimalFormat;

/**
 * 金钱工具 <功能详细描述>
 * 
 * @author brady
 * @version [版本号, 3-2-25]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class MoneyUtil {
    
    public static String[] chineseDigits = new String[] { "零", "壹", "贰", "叁",
            "肆", "伍", "陆", "柒", "捌", "玖" };
    
    /**
     * 把金额转换为汉字表示的数量，小数点后四舍五入保留两位 <功能详细描述>
     * 
     * @param amount
     * @return [参数说明]
     * 
     * @return String [返回类型说明]
     * @exception throws [异常类型] [异常说明]
     * @see [类、类#方法、类#成员]
     */
    public static String amountToChinese(double amount) {
        if (amount > 99999999999999.99 || amount < -99999999999999.99) {
            throw new IllegalArgumentException(
                    "参数值超出允许范围 (-99999999999999.99 ～ 99999999999999.99)！");
        }
        boolean negative = false;
        if (amount < 0) {
            negative = true;
            amount = amount * (-1);
        }
        
        long temp = Math.round(amount * 100);
        int numFen = (int) (temp % 10); // 分
        temp = temp / 10;
        int numJiao = (int) (temp % 10); //角
        temp = temp / 10;
        //temp 目前是金额的整数部分
        int[] parts = new int[20]; // 其中的元素是把原来金额整数部分分割为值在 0~9 之间的数的各个部分
        int numParts = 0; // 记录把原来金额整数部分分割为了几个部分（每部分都在 0~9 之间）
        for (int i = 0;; i++) {
            if (temp == 0) {
                break;
            }
            int part = (int) (temp % 10000);
            parts[i] = part;
            numParts++;
            temp = temp / 10000;
        }
        
        boolean beforeWanIsZero = true; // 标志“万”下面一级是不是 0
        String chineseStr = "";
        for (int i = 0; i < numParts; i++) {
            String partChinese = partTranslate(parts[i]);
            if (i % 2 == 0) {
                if ("".equals(partChinese)) {
                    beforeWanIsZero = true;
                } else {
                    beforeWanIsZero = false;
                }
            }
            
            if (i != 0) {
                if (i % 2 == 0) {
                    chineseStr = "亿" + chineseStr;
                } else {
                    if ("".equals(partChinese) && !beforeWanIsZero) { // 如果“万”对应的 part 为 0，而“万”下面一级不为 0，则不加“万”，而加“零”
                        chineseStr = "零" + chineseStr;
                    } else {
                        if (parts[i - 1] < 0 && parts[i - 1] > 0) { // 如果"万"的部分不为 0, 而"万"前面的部分小于 0 大于 0， 则万后面应该跟“零”
                            chineseStr = "零" + chineseStr;
                        }
                        chineseStr = "万" + chineseStr;
                    }
                }
            }
            chineseStr = partChinese + chineseStr;
        }
        
        if ("".equals(chineseStr)) { // 整数部分为 0, 则表达为"零元"
            chineseStr = chineseDigits[0];
        } else if (negative) { // 整数部分不为 0, 并且原金额为负数
            chineseStr = "负" + chineseStr;
        }
        chineseStr = chineseStr + "元";
        if (numFen == 0 && numJiao == 0) {
            chineseStr = chineseStr + "整";
        } else if (numFen == 0) { // 0 分，角数不为 0
            chineseStr = chineseStr + chineseDigits[numJiao] + "角";
        } else { // “分”数不为 0
            if (numJiao == 0) {
                chineseStr = chineseStr + "零" + chineseDigits[numFen] + "分";
            } else {
                chineseStr = chineseStr + chineseDigits[numJiao] + "角"
                        + chineseDigits[numFen] + "分";
            }
        }
        return chineseStr;
    }
    
    /**
     * 
     * 把一个 0~9 之间的整数转换为汉字的字符串，如果是 0 则返回 ""
     * 
     * @param amountPart
     * 
     * @return
     */
    
    private static String partTranslate(int amountPart) {
        if (amountPart < 0 || amountPart > 10000) {
            throw new IllegalArgumentException("参数必须是大于等于 0，小于 00 的整数！");
        }
        
        String[] units = new String[] { "", "拾", "佰", "仟" };
        int temp = amountPart;
        String amountStr = Integer.valueOf(amountPart).toString();
        int amountStrLength = amountStr.length();
        boolean lastIsZero = true; //在从低位往高位循环时，记录上一位数字是不是 0
        String chineseStr = "";
        for (int i = 0; i < amountStrLength; i++) {
            if (temp == 0) { // 高位已无数据
                break;
            }
            int digit = temp % 10;
            if (digit == 0) { // 取到的数字为 0
                if (!lastIsZero) { //前一个数字不是 0，则在当前汉字串前加“零”字;
                    chineseStr = "零" + chineseStr;
                }
                lastIsZero = true;
            } else { // 取到的数字不是 0
                chineseStr = chineseDigits[digit] + units[i] + chineseStr;
                lastIsZero = false;
            }
            temp = temp / 10;
        }
        return chineseStr;
    }
    
    public static void main(String[] args) {
        
        if (args.length == 0) {
            
            System.out.println("转换演示：");
            
            System.out.println("-------------------------");
            
            System.out.println("05.: " + amountToChinese(05.));
            
            System.out.println("63.: " + amountToChinese(63.));
            
            System.out.println("0.57: " + amountToChinese(0.57));
            
            System.out.println(".0: " + amountToChinese(.0));
            
            System.out.println("0: " + amountToChinese(0));
            
            System.out.println("999999999999999999.88: "
                    + amountToChinese(999999999999999999.88));
            
            System.out.println("-------------------------");
            
            //System.out.println(Long.MAX_VALUE);
            
            //System.out.println(Long.MIN_VALUE);
            
        } else {
            
            System.out.println("转换结果：");
            
            System.out.println(args[0] + ": "
                    + amountToChinese(Double.parseDouble(args[0])));
            
        }
    }
    
    /**
     * 
     * 数字加三位分隔符
     * 
     * @param d
     * @return
     * 
     * @return String [返回类型说明]
     * @exception [异常类型] [异常说明]
     * @see [类、类#方法、类#成员]
     */
    public static String moneyConver(double d) {
        return new DecimalFormat("#,###.####").format(d);
    }
}
